package cn.kennylee.codehub.mybatis.das.extension;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.kennylee.codehub.mybatis.das.eo.BaseEo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.util.Collection;
import java.util.Objects;

/**
 * <p> 批量保存的ID设置 </p>
 * <p>Created on 2025/2/10.</p>
 *
 * @author kennylee
 * @since 0.0.1
 */
@Slf4j
public class BatchSaveIdProvider<T extends BaseEo<P>, P extends Serializable> implements BatchSavePropsProvider<T, P> {

    @Override
    @SuppressWarnings("unchecked")
    public void provide(Collection<T> entities, TableInfo tableInfo) {

        if (CollUtil.isEmpty(entities)) {
            return;
        }

        if (false == tableInfo.havePK()) {
            return;
        }

        IdType idType = tableInfo.getIdType();

        if (Objects.isNull(idType)) {
            log.debug("主键类型为空，使用默认的主键类型分配");
            defaultIdTypeAssign(entities, tableInfo);
            return;
        }

        // 自增
        if (idType == IdType.AUTO) {
            return;
        }

        switch (idType) {
            case ASSIGN_UUID:
                log.debug("主键类型为 ASSIGN_UUID，为实体分配主键");
                entities.forEach(entity -> {
                    if (Objects.nonNull(entity.getId())) {
                        return;
                    }
                    if (Boolean.FALSE == tableInfo.getKeyType().equals(String.class)) {
                        throw new IllegalArgumentException("主键类型为 ASSIGN_UUID，但实体主键类型不是 String");
                    }
                    entity.setId((P) IdUtil.fastSimpleUUID());
                });
                break;
            case ASSIGN_ID:
                log.debug("主键类型为 ASSIGN_ID，为实体分配主键");
                assignEntitySnowflakeId(entities, tableInfo);
                break;
            case INPUT:
                // 手动输入，用户需自行设置
                break;
            default:
                break;
        }
    }

    /**
     * 为实体分配雪花算法生成的主键
     *
     * @param entityList 实体列表
     * @param tableInfo  表信息
     */
    @SuppressWarnings("unchecked")
    protected void assignEntitySnowflakeId(Collection<T> entityList, TableInfo tableInfo) {
        entityList.forEach(entity -> {
            if (Objects.nonNull(entity.getId())) {
                return;
            }
            if (tableInfo.getKeyType().equals(Long.class)) {
                entity.setId((P) Long.valueOf(IdUtil.getSnowflakeNextId()));
            } else if (tableInfo.getKeyType().equals(String.class)) {
                entity.setId((P) IdUtil.getSnowflakeNextIdStr());
            } else {
                throw new IllegalArgumentException("不支持的主键类型: " + tableInfo.getKeyType());
            }
        });
    }

    /**
     * 默认的主键类型分配
     *
     * @param entityList 实体列表
     * @param tableInfo  表信息
     */
    protected void defaultIdTypeAssign(Collection<T> entityList, TableInfo tableInfo) {
        assignEntitySnowflakeId(entityList, tableInfo);
    }
}
